home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
FROMUTS
/
UNIXLIB37B
/
src
/
c
/
alloc
< prev
next >
Wrap
Text File
|
1993-02-11
|
6KB
|
378 lines
static char sccs_id[] = "@(#) alloc.c 5.0 "__DATE__" HJR";
/* alloc.c (c) Copyright 1990 H.Rogers */
/* features multiple free lists hashed on block size */
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#ifdef M_DEBUG
#include <stdio.h>
#include <signal.h>
static int __m_fail(char *exp,char *file,int line)
{
fprintf(stderr,"\n\"%s\", line %d: Assertion failed: %s\n",file,line,exp);
raise(SIGABRT);
return(0);
}
#define assert(x) (void)((x) ? 0 : __m_fail(#x,__FILE__,__LINE__))
#define addr(x) ((x) ? (*((int *)(x)) | 1) : 0)
#define MAGIC 0x4349474d
#endif
extern void *sbrk(int);
typedef struct _blk
{
#ifdef M_DEBUG
int magic;
#endif
struct _blk *next;
size_t size;
} blk;
#ifdef M_DEBUG
#define BLKSIZ 16 /* smallest power of 2 >= sizeof(blk) */
#else
#define BLKSIZ 8
#endif
#define blkalign(x) (((x) + (BLKSIZ<<1) - 1) & (~(BLKSIZ - 1)))
#define NFL 8
static blk __fl[NFL];
static size_t __flmin[NFL] =
{
4096 + BLKSIZ,
1024 + BLKSIZ,
256 + BLKSIZ,
64 + BLKSIZ,
32 + BLKSIZ,
16 + BLKSIZ,
8 + BLKSIZ,
0 + BLKSIZ /* catchall */
};
#define MEMINC 12 /* sbrk() memory block bit alignment */
void __allocinit(void)
{
register blk *b;
register int i;
#ifdef M_DEBUG
assert(sizeof(struct _blk) <= BLKSIZ);
#endif
for (i = 0; i < NFL; i++)
{
b = __fl + i;
b->next = b;
b->size = BLKSIZ;
#ifdef M_DEBUG
b->magic = MAGIC;
#endif
}
}
static blk *findblk(register int i,register blk *a)
{
register blk *b,*p;
p = __fl + i;
b = p->next;
#ifdef M_DEBUG
assert(addr(p));
assert(p->magic == MAGIC);
#endif
while (b > p)
{
#ifdef M_DEBUG
assert(addr(b));
assert(b->magic == MAGIC);
#endif
if (b >= a) break;
p = b;
b = b->next;
}
return(p);
}
#define addblk(i,n,p) ((n)->next = (p)->next,(p)->next = (n))
#define delblk(i,b,p) ((p)->next = (b)->next)
static void concatblk(register blk *a,register blk *p)
{
register blk *b;
if (!p) return;
b = p->next;
while ((char *)a + a->size == (char *)b)
{
a->size += b->size;
#ifdef M_DEBUG
b->magic = 0;
#endif
b = b->next;
}
p->next = b;
}
static int flindex(register int size)
{
register int i;
for (i = 0; size < __flmin[i]; i++);
return(i);
}
static blk *findsize(register int i,register int size,register blk **p_)
{
register blk *b,*p;
p = __fl + i;
b = p->next;
while (b > p)
{
if (b->size >= size)
{ delblk(i,b,p); break; }
p = b;
b = b->next;
}
if (p_) *p_ = p; return(b);
}
void *malloc(register size_t size)
{
register blk *b;
register int i;
blk *p;
if (!size) return(0);
size = blkalign(size);
i = flindex(size);
b = findsize(i,size,&p);
if (b <= p)
{
register void *m;
register int _size;
_size = ((size>>MEMINC) + 1)<<MEMINC;
if ((m = sbrk(_size)) == (void *)-1) return(0);
if ((char *)p + p->size == (char *)m)
{
b = p;
p = findblk(i,b);
delblk(i,b,p);
b->size += _size;
}
else
{
b = (blk *)m;
b->size = _size;
#ifdef M_DEBUG
b->magic = MAGIC;
#endif
}
}
#ifdef M_DEBUG
assert(addr(b));
assert(b->magic == MAGIC);
#endif
if (b->size > (size + __flmin[i]))
{
register blk *n;
n = (blk *)((char *)b + size);
addblk(i,n,p);
n->size = b->size - size;
#ifdef M_DEBUG
n->magic = MAGIC;
#endif
b->size = size;
}
return((void *)((char *)b + BLKSIZ));
}
void *realloc(register void *_a,register size_t size)
{
register blk *a;
register int i;
blk *p;
if (!(_a)) return(malloc(size));
if (!size) { free(_a); return(0); }
size = blkalign(size);
#ifdef M_DEBUG
assert(addr(_a));
#endif
a = (blk *)((char *)_a - BLKSIZ);
#ifdef M_DEBUG
assert(addr(a));
assert(a->magic == MAGIC);
#endif
i = flindex(a->size);
p = findblk(i,a);
concatblk(a,p);
if (a->size < size)
{
if ((char *)p + p->size == (char *)a && p->size + a->size >= size)
{
register blk *b;
#ifdef M_DEBUG
assert(addr(p));
assert(p->magic == MAGIC);
#endif
b = p;
p = findblk(i,b);
delblk(i,b,p);
b->size += a->size;
#ifdef M_DEBUG
a->magic = 0;
#endif
memmove((char *)b + BLKSIZ,_a,a->size - BLKSIZ);
_a = (char *)(a = b) + BLKSIZ;
}
else
{
register void *m;
register int _size;
_size = ((size>>MEMINC) + 1)<<MEMINC;
if ((m = sbrk(_size)) == (void *)-1) return(0);
if ((char *)a + a->size == (char *)m)
a->size += _size;
else
{
register blk *b;
addblk(i,a,p);
b = (blk *)m;
b->size = _size;
#ifdef M_DEBUG
b->magic = MAGIC;
#endif
memcpy((char *)b + BLKSIZ,_a,a->size - BLKSIZ);
_a = (char *)(a = b) + BLKSIZ;
}
}
}
i = flindex(size);
if (a->size > (size + __flmin[i]))
{
register blk *n;
p = findblk(i,a);
n = (blk *)((char *)a + size);
addblk(i,n,p);
n->size = a->size - size;
#ifdef M_DEBUG
n->magic = MAGIC;
#endif
a->size = size;
}
return(_a);
}
void free(register void *_a)
{
register blk *a,*p;
register int i;
if (!_a) return;
#ifdef M_DEBUG
assert(addr(_a));
#endif
a = (blk *)((char *)_a - BLKSIZ);
#ifdef M_DEBUG
assert(addr(a));
assert(a->magic == MAGIC);
#endif
i = flindex(a->size);
p = findblk(i,a);
concatblk(a,p);
if ((char *)p + p->size == (char *)a)
{
p->size += a->size;
#ifdef M_DEBUG
a->magic = 0;
#endif
}
else
addblk(i,a,p);
}
#ifdef M_DEBUG
void __m_debug(void) /* dump free lists */
{
register blk *b;
register int i;
for (i = 0; i < NFL; i++)
{
printf("\nfl: %d ( >= %d )\n",i,__flmin[i] - BLKSIZ);
b = __fl + i; do
{
b = b->next;
printf("%7x: next: %7x [%7x] size: %x\n",b,b->next,
(char *)b + b->size,b->size - BLKSIZ);
assert(addr(b));
assert(b->magic == MAGIC);
}
while (b->next > b);
}
putchar('\n');
}
#endif